#pragma once
#include <cstring>
#include <string>
#include <vector>
#include <mutex>

#include "types.h"

using namespace std;
#define TYPE_ASK 0
#define TYPE_RES 0x10
#define TYPE_IND 0x20
const int bufSize = 256;
const int headSize = 16;
const int dataSize = 240;
struct package
{
	const u8 st = 0xFF;
	u8 type;
	u8 from;
	u8 len;
	u32 stamp;
	u32 num;
	u32 tot;
	char data[dataSize];
	/*
	 * |st       |type      |from    |len     |
	 * |stamp                                 |
	 * |num                                   |
	 * |tot                                   |
	 * |data ...                              |
	 * |data ...                              |
	 */
	package(){}

	package(
		u8 type,
		u8 from,
		u8 dataLen,
		u32 stamp,
		u32 num,
		u32 tot,
		const char* data
	)
	{
		this->type = type;
		this->from = from;
		this->len = dataLen + headSize;
		this->stamp = stamp;
		this->num = num;
		this->tot = tot;
		if (data != nullptr)
		{
			memcpy(this->data, data, dataLen);
		}
	}

	bool isLast()
	{
		return num == tot - 1;
	}
	bool isFirst()
	{
		return num == 0;
	}
};

inline void compose(queue<package>& pList, char*& dst, u32& len)
{
	u32 tot = pList.front().tot;
	dst = new char[tot * dataSize];
	len = 0;
	char* p = dst;
	while (!pList.empty())
	{
		u8 l = pList.front().len - headSize;
		memcpy(p + len, pList.front().data, l);
		len += l;
		pList.pop();
	}
}

inline void split(queue<package>& pList, u8 type, u8 from, u32 stamp, const char* src, u32 len)
{
	len += 1;
	u32 tot = len / dataSize + (len % dataSize > 0);
	for (u32 num = 0; num < tot; num++)
	{
		pList.emplace(type, from, num == tot - 1 ? len % dataSize : dataSize, stamp, num, tot, src + num * dataSize);
	}
}